import time


class MyRetry:
    def __init__(self,
                 times=3,
                 return_obj=None,
                 return_msg=None,
                 msg_return_params=False,
                 return_err_cause=True,
                 show_process_err=True,
                 sleep_time=0
                 ):
        """
        重试模块
        :param times: 重试次数
        :param return_obj: 重试失败会返回的对象，如果参数为None则不返回直接raise，否则返回除None外指定对象
        :param return_msg: 自定义重试失败后打印的消息
        :param msg_return_params: 是否要打印传入的参数
        :param return_err_cause: 是否打印报错原因
        :param show_process_err: 是否打印重试过程中的提示
        :param sleep_time: 暂停时间
        """
        self.times = times
        self.return_obj = return_obj
        self.return_msg = return_msg
        self.msg_return_params = msg_return_params
        self.return_err_cause = return_err_cause
        self.show_process_err = show_process_err
        self.sleep_time = sleep_time

    def __call__(self, fun):
        retry_times = self.times
        return_obj = self.return_obj
        return_msg = self.return_msg
        msg_return_params = self.msg_return_params
        return_err_cause = self.return_err_cause
        show_process_err = self.show_process_err
        sleep_time = self.sleep_time

        def retry_handle(*args, **kwargs):
            msg = f'函数: {fun.__name__}   重试达到最大次数{retry_times}次'
            cause = ''
            for times in range(retry_times):
                try:
                    fun_res = fun(*args, **kwargs)
                except Exception as e:
                    cause = e
                    if times == retry_times - 1:
                        if return_obj is not None and return_msg is None:
                            msg += f' 返回自定义对象: {return_obj} '
                            return return_obj
                        elif return_obj is None and return_msg is not None:
                            msg += f' 消息: {return_msg} '
                        elif return_obj is not None and return_msg is not None:
                            msg += f' 返回自定义对象: {return_obj}  消息: {return_msg} '
                            return return_obj
                        else:
                            msg += f' 重试达到最大次数({retry_times}次 '
                            raise
                    else:
                        if show_process_err:
                            pass
                        if sleep_time:
                            time.sleep(sleep_time)
                else:
                    return fun_res
                finally:
                    if times == retry_times - 1 and msg:
                        if msg_return_params:
                            msg += f' 参数: {args} {kwargs} '
                        if return_err_cause:
                            msg += f'原因: {cause}'

        return retry_handle
